use std::io;

use thiserror::Error;


#[derive(Debug, Error)]
enum TestError {
    #[error("env error: {0}")]
    VarError(String),

    #[error("HTML to Markdown conversion error: {0}")]
    IoError(#[from] io::Error),

    #[error("Prompt error: {0}")]
    PromptError(#[from] rig::completion::PromptError),
}



#[cfg(test)]
mod tests {
    use std::env;

    use rig::{agent::AgentBuilder, completion::Prompt, message::{Message, Text, UserContent}, providers::openai, OneOrMany};

    use super::*;

    /// 测试使用 OpenAI 模型将 HTML 转换为 Markdown
    #[tokio::test]
    async fn test_html_to_markdown() -> Result<(), TestError> {
        dotenvy::from_path("../../.env").ok();

        let target_file_path = "resources/use.html";
        let content = std::fs::read_to_string(target_file_path)?;

        // 尝试使用 OpenAI 模型而不是 Gemini
        let api_key = env::var("OPENAI_API_KEY").map_err(|e| TestError::VarError(e.to_string()))?;
        let base_url = env::var("OPENAI_BASE_URL").map_err(|e| TestError::VarError(e.to_string()))?;
        let client = openai::Client::from_url(&api_key, &base_url);
        let model = client.completion_model("gpt-4.1-mini");
        let system = r#"
Please convert the following HTML code into Markdown format.

**Important Note:** This HTML might contain non-standard or non-semantic tag usage. For example:
*   Code blocks might not use `<pre>` or `<code>` tags, but instead use `<div>` or other generic tags.
*   Bold text might use `<b>` tags, or be implemented via CSS classes (e.g., `<span class="bold">`), rather than the standard `<strong>`.
*   Headings might not use `<h1>`-`<h6>` tags, but instead use `<div>` or `<p>` tags with specific styling (e.g., larger font size, bold).
*   Lists might not use `<ul>`/`<ol>` and `<li>`, but instead use `<p>` tags preceded by bullet points or numbers.

**Your task is to:**
1.  Carefully analyze the HTML structure, content, and potential styling clues (if any).
2.  **Based on context and inferred semantics**, convert the HTML elements into the most appropriate Markdown syntax.
    *   **Example (Code Block):** If a `<div>` or `<p>` contains multiple lines of text, features a monospace font, or is clearly a code snippet, convert it into a Markdown code block (```).
    *   **Example (Bold):** If text is wrapped in `<b>` tags, or its styling indicates it's bold, use Markdown's bold syntax (`**text**`).
    *   **Example (Heading):** If the text within a `<div>` or `<p>` looks like a heading (e.g., larger font, bold, on its own line, at the start of a content section), infer its visual hierarchy and use the corresponding Markdown heading syntax (`# H1`, `## H2`, etc.).
    *   **Example (List):** If multiple consecutive `<p>` tags start with bullet points (like `-`, `*`) or numbers (like `1.`, `2.`), convert them into a Markdown list.
3.  Ensure the resulting Markdown accurately reflects the structure and formatting intent of the original content.
4.  Prioritize handling common Markdown elements: headings, paragraphs, lists (ordered and unordered), code blocks (inline and block-level), bold, italics, links, images, etc.

Please process the following HTML:
"#;
        let agent = AgentBuilder::new(model)
            .preamble(system)
            .temperature(0.4)
            //.context(&content)
            .build();

        // 创建包含 HTML 内容的消息
        let html_content = UserContent::Text(Text { text: content });

        // 使用 OneOrMany::many 创建包含多个内容的消息
        let message = Message::User {
            content: OneOrMany::many(vec![html_content]).unwrap(),
        };

        let response = agent.prompt(message).await?;

        // 将转换后的 Markdown 保存到文件
        let output_path = "resources/html_to_markdown_result.md";
        std::fs::write(output_path, response)?;
        println!("HTML has been successfully converted to Markdown and saved to: {}", output_path);
        Ok(())
    }
}
